package com.jy.framework.dto;

import com.jy.framework.base.TreeEntity;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: JuiceYan
 * @Description: 生成树
 * @Class: TreeDTO
 * @Date: 11:06 2018/12/12
 */
public class TreeEntityDTO {
    private static final long serialVersionUID = 1L;

//    public static final String ID = "id";
//    public static final String PID = "parent_id";
//    public static final String SORT = "order_num";
//    public static final String CHILDREN = "subCategories";
//    public static final String PARENT_NAME = "parent_name";
//    public static final String NAME = "name";
//    public static final String ICON = "icon";
    public static final String ROOT = "根目录";

    public  static <T extends TreeEntity> List<T> createTree(Long pid, List<T> list) {
        Map<Long, List<T>> map = groupList(list);
        return toTree(pid, map);
    }

    private static <T extends TreeEntity> List<T> toTree(Long pid, Map<Long, List<T>> map) {
        return Optional.ofNullable(map.get(pid)).orElseGet(() -> new ArrayList<>()).stream().filter(x -> x.getParentId().equals(pid)).sorted(Comparator.comparing(x -> ((Long) x.getOrderNum()))).map(x -> {
            x.setNodes(toTree(x.getId(), map));
            return x;
//            return treeNodeMap(x, toTree(x.getId(), map));
        }).collect(Collectors.toList());
    }

    private static <T extends TreeEntity>  Map<Long, List<T>> groupList(List<T> list) {
        Map<Object, T> map = list.stream().collect(Collectors.toMap(key -> key.getId(), value -> value));
        return list.stream().map(node -> {
            T objectMap = map.get(node.getParentId());
            String value = ROOT;
            if (objectMap != null) {
                value = objectMap.getName();
            }
            node.setParentName(value);
            return node;
        }).collect(Collectors.groupingBy(parent -> Long.valueOf(String.valueOf(parent.getParentId()))));
    }

    private static  <T extends TreeEntity> T treeNodeMap(T treeNode, List<T> children) {
        treeNode.setNodes(children);
        return treeNode;
    }
}
